/*
 * Copyright (C) 2020/12/13
 * by zhuyk
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.fred.colorpicker

import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
import android.graphics.*
import android.os.Build
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.annotation.ColorInt
import androidx.annotation.RequiresApi
import com.fred.colorpicker.listener.GrayColorListener
import com.fred.colorpicker.indicator.ColorWheelIndicator
import kotlin.math.max
import kotlin.math.min

/**
 * 彩色 - 灰度 选择条
 */
class GraySeekBar:FrameLayout {

    private val minInterval = 1000/60
    private var lastPassedEventTime = 0L

    private var indicator:ColorWheelIndicator?= null
    private val barView by lazy {
        GraySeekBarView(context).apply {
            parentView = this@GraySeekBar
        }
    }
    private val currentPoint by lazy {
        PointF()
    }

    var onlyUpdateOnTouchEventUp = false
    var selectorColorListener: GrayColorListener?=null

    constructor(context: Context) : super(context){init()}
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs){init()}
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
            super(context, attrs, defStyleAttr){init()}
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) :
            super(context, attrs, defStyleAttr, defStyleRes){init()}

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        val height = MeasureSpec.getSize(heightMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)

        val realHeight = if (heightMode == MeasureSpec.EXACTLY){
            height
        }else{
            val maxHeight = max(barView.measuredHeight,indicator?.minimumHeight()?:0)
            val d = context.dip(2F).toInt()
            indicator?.layoutParams?.height = (maxHeight + d)
            maxHeight + paddingTop + paddingBottom + d
        }
        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),realHeight)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        val centreY = (h - paddingTop - paddingBottom)/2F
        currentPoint.y = centreY
        val bean = indicator?.initGraySeekBar(w,centreY)
        bean?.apply {
            barView.setColor(color,saturation, brightness)
            currentPoint.x = bean.point.x
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when(event?.actionMasked?:-1){
            MotionEvent.ACTION_DOWN,
            MotionEvent.ACTION_MOVE->{
                val current = System.currentTimeMillis()
                if (current - lastPassedEventTime > minInterval){
                    lastPassedEventTime = current
                    event?.apply { update(this.x,false) }
                    return true
                }
            }
            MotionEvent.ACTION_UP->{
                event?.apply { update(this.x,true) }
                return true
            }
        }
        return super.onTouchEvent(event)
    }

    fun setIndicator(indicator: ColorWheelIndicator) {
        removeView(this.indicator)
        this.indicator = indicator.copy()
        this.indicator?.isDrawCentre = false
        this.indicator?.isSelected = true
        val layoutParams = LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT)
        addView(this.indicator, layoutParams)
        val bean = this.indicator?.initGraySeekBar(width,currentPoint.y)
        currentPoint.x = bean?.point?.x?:0F
    }

    fun setColor(@ColorInt color:Int,saturation:Float,brightness:Float){
        barView.setColor(color,saturation, brightness)
        update(currentPoint.x,false)
       indicator?.setGraySeekBarConfig(color, saturation, brightness)
    }

    fun callback(){
        val color = barView.getColor(currentPoint.x)
        selectorColorListener?.onSelectorColor(color)
    }

    private fun init(){
        setPadding(10,10,10,10)
        val layoutParams = LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT)
        addView(barView,layoutParams)
    }

    private fun update(x:Float,isTouchUp:Boolean){
        currentPoint.x = min(max(x,barView.paddingStart.toFloat()),(barView.width - barView.paddingStart).toFloat())
        if (!onlyUpdateOnTouchEventUp || isTouchUp){
            callback()
        }
        indicator?.setCurrentPoint(currentPoint)
        if (isTouchUp){
            indicator?.setGraySeekBarPositionConfig(currentPoint.x/width)
        }
    }

}
